﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Security.Cryptography;
using System.IO;
using System.Collections;

namespace UFSSServerClasses
{
    public static class FileAccess
    {
        private static MD5 md5 = MD5.Create();
        public static string getHash(byte[] buffer)
        {
            buffer = md5.ComputeHash(buffer);
            StringBuilder sbuilder = new StringBuilder();
            for (int i = 0; i < buffer.Length; i++)
            {
                sbuilder.Append(buffer[i].ToString("x2"));
            }
            return sbuilder.ToString();
        }
        public static ArrayList getTopFiles(int amount)
        {
            ArrayList file = new ArrayList();
            UFSSFile f = null;
            try
            {
                using (SqlConnection connection = new SqlConnection(DBAccess.getConString()))
                {
                    connection.Open();
                    SqlCommand c = new SqlCommand("gettopfiles", connection);
                    c.CommandType = System.Data.CommandType.StoredProcedure;
                    c.Parameters.Add(new SqlParameter("@num", amount));
                    SqlDataReader r = c.ExecuteReader();
                    while (r.Read())
                    {
                        f = new UFSSFile();
                        f.filename = r["filename"].ToString();
                        f.userid = (int)r["fileid"];
                        f.filesize = (int)r["filesize"];
                        f.dateadded = (DateTime)r["dateadded"];
                        f.downloads = (int)r["downloadcount"];
                        f.ownerid = (int)r["fileowner"];
                        file.Add(f);
                    }
                    connection.Close();
                    return file;
                }
            }
            catch
            {
                return null;
            }
        }
        public static ArrayList getFilesByDate(DateTime oldest, DateTime newest)
        {
            ArrayList file = new ArrayList();
            UFSSFile f = null;
            try
            {
                using (SqlConnection connection = new SqlConnection(DBAccess.getConString()))
                {
                    connection.Open();
                    SqlCommand c = new SqlCommand("getfilesbydate", connection);
                    c.CommandType = System.Data.CommandType.StoredProcedure;
                    c.Parameters.Add(new SqlParameter("@startdate", oldest));
                    c.Parameters.Add(new SqlParameter("@enddate", newest));
                    SqlDataReader r = c.ExecuteReader();
                    while (r.Read())
                    {
                        UFSSSubscription sub = null;
                        int subid;
                        if (Int32.TryParse(r["subscriptionid"].ToString(), out subid))
                            sub = SubAccess.getSubscriptionInfo((int)r["subscriptionid"]);
                        f = new UFSSFile((int)r["fileid"], (string)r["filename"], (int)r["filesize"],
                            (DateTime)r["dateadded"], null, (int)r["downloadcount"]);
                        f.setOwnerid((int)r["fileowner"]);
                        if (sub != null)
                            f.subname = sub.subName;

                        file.Add(f);
                    }
                    connection.Close();
                    return file;
                }
            }
            catch
            {
                return null;
            }
        }
        public static ArrayList searchFiles(string query)
        {
            try
            {
                using (SqlConnection connection = new SqlConnection(DBAccess.getConString()))
                {
                    ArrayList filelist = new ArrayList();
                    connection.Open();
                    SqlCommand c = new SqlCommand("filesearch", connection);
                    c.CommandType = System.Data.CommandType.StoredProcedure;
                    c.Parameters.Add(new SqlParameter("@search", query));
                    SqlDataReader r = c.ExecuteReader();
                    while (r.Read())
                    {
                        UFSSFile file = new UFSSFile(r.GetInt32(3),r.GetString(1),r.GetInt32(4),r.GetDateTime(2),null,r.GetInt32(5),r.GetString(6));
                        file.ownerid = (int)r["fileid"];
                        filelist.Add(file);
                        
                       

                    }
                    connection.Close();
                    return filelist;

                }
            }
            catch
            {
                return null;
            }
        }
        public static string uploadFile(int userid, byte[] filecontent, string filename, int subscriptionid = -1)
        {
            try
            {
                using (SqlConnection connection = new SqlConnection(DBAccess.getConString()))
                {
                    string hashvalue = getHash(filecontent);
                    connection.Open();
                    SqlCommand c = new SqlCommand("addfile", connection);
                    c.CommandType = System.Data.CommandType.StoredProcedure;
                    c.Parameters.Add(new SqlParameter("@fileowner", userid));
                    c.Parameters.Add(new SqlParameter("@filecontent", filecontent));                    
                    c.Parameters.Add(new SqlParameter("@filehash", hashvalue));
                    c.Parameters.Add(new SqlParameter("@filename", filename));
                    c.Parameters.Add(new SqlParameter("@filesize", filecontent.LongLength));
                    c.Parameters.Add(new SqlParameter("@subscriptionid", subscriptionid));

                    c.ExecuteNonQuery();
                    connection.Close();
                    return hashvalue;
                }
            }
            catch
            {
                return null;
            }
        }
        public static byte[] downloadFile(int fileid, int userid)
        {
            try
            {
                using (SqlConnection connection = new SqlConnection(DBAccess.getConString()))
                {
                    byte[] filedata;
                    connection.Open();
                    SqlCommand c = new SqlCommand("downloadfile", connection);
                    c.CommandType = System.Data.CommandType.StoredProcedure;
                    c.Parameters.Add(new SqlParameter("@fileid", fileid));
                    c.Parameters.Add(new SqlParameter("@userid", userid));
                    SqlDataReader r = c.ExecuteReader();
                    while (r.Read())
                    {
                        filedata = new byte[r.GetInt32(1)];
                        filedata = r.GetSqlBytes(0).Value;
                        connection.Close();
                        return filedata;
                        
                    }
                    return null;
                    
                }
            }
            catch
            {
                return null;
            }
        }
        public static int getFileSize(int fileid)
        {
            int result = -1;
            try
            {
                using (SqlConnection connection = new SqlConnection(DBAccess.getConString()))
                {
                    connection.Open();
                    SqlCommand c = new SqlCommand("getfilesize", connection);
                    c.CommandType = System.Data.CommandType.StoredProcedure;
                    c.Parameters.Add(new SqlParameter("@fileid", fileid));
                    SqlDataReader r = c.ExecuteReader();
                    while (r.Read())
                    {
                        result = Int32.Parse(r.GetValue(0).ToString()); 
                    }
                    connection.Close();
                    return result;
                }
            }
            catch
            {
                return -1;
            }
        }
        public static bool deleteFile(int fileid, int userid)
        {
            try
            {
                using (SqlConnection connection = new SqlConnection(DBAccess.getConString()))
                {
                    connection.Open();
                    SqlCommand c = new SqlCommand("delfile", connection);
                    c.CommandType = System.Data.CommandType.StoredProcedure;
                    c.Parameters.Add(new SqlParameter("@fileid", fileid));
                    c.Parameters.Add(new SqlParameter("@userid", userid));
                    int temp = c.ExecuteNonQuery();
                    if (temp == 0)
                        return false;
                    
                    connection.Close();
                    return true;
                }
            }
            catch
            {
                return false;
            }
        }

        public static UFSSFile getFileInfo(int fileid)
        {
           
            try
            {
                UFSSFile file;
                using (SqlConnection connection = new SqlConnection(DBAccess.getConString()))
                {
                    connection.Open();
                    SqlCommand c = new SqlCommand("getfileinfo", connection);
                    c.CommandType = System.Data.CommandType.StoredProcedure;
                    c.Parameters.Add(new SqlParameter("@fileid", fileid));
                    SqlDataReader r = c.ExecuteReader();
                    if(r.Read())
                    {
                        UFSSSubscription sub = SubAccess.getSubscriptionInfo((int)r["subscriptionid"]);
                        file = new UFSSFile((int)r["fileid"], r["filename"].ToString(), (int)r["filesize"], (DateTime)r["dateadded"], sub.subName, (int)r["downloadcount"], r["filehash"].ToString());
                        file.setOwnerid((int)r["fileowner"]);
                        return file;
                    }
                    connection.Close();
                    
                    return null;
                }
            }
            catch
            {
                return null;
            }

        }
        public static ArrayList getFiles(int userid)
        {
            ArrayList file = new ArrayList();
            UFSSFile f = null;
            try
            {
                using (SqlConnection connection = new SqlConnection(DBAccess.getConString()))
                {
                    connection.Open();
                    SqlCommand c = new SqlCommand("getuserfiles", connection);
                    c.CommandType = System.Data.CommandType.StoredProcedure;
                    c.Parameters.Add(new SqlParameter("@userid", userid));
                    SqlDataReader r = c.ExecuteReader();
                    while (r.Read())
                    {
                        UFSSSubscription sub = null;
                        int subid;
                        if (Int32.TryParse(r["subscriptionid"].ToString(),out subid))
                            sub = SubAccess.getSubscriptionInfo((int)r["subscriptionid"]);
                        f = new UFSSFile((int)r["fileid"], (string)r["filename"], (int)r["filesize"],
                            (DateTime)r["dateadded"], null, (int)r["downloadcount"]);
                        f.setOwnerid((int)r["fileowner"]);
                        if (sub != null)
                            f.subname = sub.subName;
                       
                        file.Add(f);
                    }
                    connection.Close();
                    return file;
                }
            }
            catch
            {
                return null;
            }
        }

        public static int getFileID(string name, int userid)
        {
            int result = -1;
            try
            {
                using (SqlConnection connection = new SqlConnection(DBAccess.getConString()))
                {
                    connection.Open();
                    SqlCommand c = new SqlCommand("getfileid", connection);
                    c.CommandType = System.Data.CommandType.StoredProcedure;
                    c.Parameters.Add(new SqlParameter("@userid", userid));
                    c.Parameters.Add(new SqlParameter("@filename", name));
                    SqlDataReader r = c.ExecuteReader();
                    while (r.Read())
                    {
                        result = (int)r.GetValue(0);
                    }
                }
            }
            catch
            {
            }

            return -1;
        }
    }
}
